package org.jeecg.modules.api.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ccqtgb.sxp.partner.security.bo.RequestData;
import com.ccqtgb.sxp.partner.security.bo.ResponseData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.entity.IdBaseEntity;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.api.utils.ApiDataUtils;
import org.jeecg.modules.api.utils.ValidatorUtils;
import org.jeecg.modules.api.vo.*;
import org.jeecg.modules.api.vo.param.PaymentConfirmationParamVo;
import org.jeecg.modules.api.vo.param.PaymentParamVo;
import org.jeecg.modules.api.vo.param.QueryOrdersParamVo;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.zcgl.entity.*;
import org.jeecg.modules.zcgl.enums.*;
import org.jeecg.modules.zcgl.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


@Api(tags = "三峡银行接口-缴费信息")
@RestController
@RequestMapping("/api/bank/order")
@Slf4j
public class OrdersApiController {

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderDetailsService orderDetailsService;


    @Autowired
    private IOrderPrestoreService orderPrestoreService;
    @Autowired
    private IReceivablesInfoService receivablesInfoService;
    @Autowired
    private ICustomerInfoService customerInfoService;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private ISysDictService dictService;
    @Autowired
    private IAssetInfoService assetInfoService;

    @ApiOperation(value = "待缴费信息-分页列表查询", notes = "待缴费信息-分页列表查询")
    @PostMapping(value = "/queryOrderList")
    public ResponseData<String> queryOrderList(@RequestBody String message) {

        RequestData<QueryOrdersParamVo> dataReslt = ApiDataUtils.getRequestData(message, QueryOrdersParamVo.class);
        try {
            QueryOrdersParamVo paramVo = dataReslt.getBody();
            String validateResult = ValidatorUtils.validateFastStr(paramVo);
            if (validateResult != null) {
                return ApiDataUtils.getResponseData(Result.errorValidation(validateResult), dataReslt.getHead());
            }
//            if (paramVo.getCustomersIds().length == 0) {
//                return ApiDataUtils.getResponseData(Result.errorValidation("客户ID不能为空"), dataReslt.getHead());
//            }
            QueryWrapper<ReceivablesInfo> queryWrapper = new QueryWrapper<>();
            ReceivablesInfo receivablesInfo = new ReceivablesInfo();
            if (StringUtils.isNotBlank(paramVo.getRecordedCompanyName())) {
                String companyId = sysDepartService.selectCompanyIdByName(paramVo.getRecordedCompanyName());
                if (StringUtils.isBlank(companyId)) {
                    return ApiDataUtils.getResponseData(Result.errorValidation("公司名称信息错误！"), dataReslt.getHead());
                }
                receivablesInfo.setRentCompanyId(companyId);
            }
            receivablesInfo.setPayStatus(PayStatusEnum.UNPAID.getStatus());
            receivablesInfo.setAmountConfirmation(YesNoEnum.YES.getStatus());
            //保证金不走三峡银行支付，排除保证金科目
            queryWrapper.lambda().ne(ReceivablesInfo::getPaymentInstructions, PaymentInstructionsEnum.CAUTION_MONEY.getStatus());
            queryWrapper.setEntity(receivablesInfo);
            final String customerSql = QueryGenerator.getCustomerSql(Arrays.asList(paramVo.getCustomerId()));
            queryWrapper.and(i -> i.apply(customerSql));
            queryWrapper.apply("DATE(pay_start_date) <= DATE('" + DateUtils.now() + "')");
            queryWrapper.lambda().orderByAsc(IdBaseEntity::getId);

            queryWrapper.select("SUM(un_amount_money) AS amount_money,lease_contract_id, customer_id, asset_sub_ids, asset_id, rent_company_id");
            queryWrapper.lambda().groupBy(ReceivablesInfo::getLeaseContractId, ReceivablesInfo::getAssetId, ReceivablesInfo::getAssetSubIds);

            //通过合同、资产和资产详情分组查询出大的欠费信息列表（其实就是分不同合同一条，但是为了手动添加的只选择资产等信息的，所有多几个分组条件）
            IPage<ReceivablesInfo> receivablesInfoIPage = receivablesInfoService.page(new Page<>(paramVo.getPageNo(), paramVo.getPageSize()), queryWrapper);
            List<ReceivablesRestBaVo> voList = new ArrayList<>();
            //遍历合同信息，查询该合同下的欠费详情
            receivablesInfoIPage.getRecords().stream().forEach(info -> {
                ReceivablesRestBaVo vo = new ReceivablesRestBaVo();
                vo.setAmountMoney(info.getAmountMoney());
                vo.setRecordedCompanyName(sysDepartService.getNameById(info.getRentCompanyId()));
                vo.setContractNum(dictService.queryTableDictTextByKey("zcgl_lease_contract_info", "contract_num", "id", info.getLeaseContractId()));
                if (StringUtils.isNotBlank(info.getAssetId())) {
                    vo.setAssetSite(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info", "site", "id", info.getAssetId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }
                if (StringUtils.isNotBlank(info.getCustomerId())) {
                    vo.setCustomerName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_customer_info", "name", "id", info.getCustomerId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }
                if (StringUtils.isNotBlank(info.getAssetSubIds())) {
                    vo.setAssetDetailsRoomName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info_sub", "room_name", "id", info.getAssetSubIds().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }


                //根据分组的信息查询待缴费信息
                LambdaQueryWrapper<ReceivablesInfo> voQueryWrapper = new LambdaQueryWrapper<>();
                voQueryWrapper.setEntity(receivablesInfo);

                if (info.getCustomerId() != null) {
                    voQueryWrapper.eq(ReceivablesInfo::getCustomerId, info.getCustomerId());
                } else {
                    voQueryWrapper.isNull(ReceivablesInfo::getCustomerId);
                }
                if (info.getAssetId() != null) {
                    voQueryWrapper.eq(ReceivablesInfo::getAssetId, info.getAssetId());
                } else {
                    voQueryWrapper.and(i -> {
                        i.isNull(ReceivablesInfo::getAssetId).or().eq(ReceivablesInfo::getAssetId, "''");
                    });
                }
                if (info.getAssetSubIds() != null) {
                    voQueryWrapper.eq(ReceivablesInfo::getAssetSubIds, info.getAssetSubIds());
                } else {
                    voQueryWrapper.isNull(ReceivablesInfo::getAssetSubIds);
                }

                voQueryWrapper.apply("DATE(pay_start_date) <= DATE('" + DateUtils.now() + "')");
                voQueryWrapper.orderByAsc(IdBaseEntity::getId);

                List<ReceivablesInfo> detailList = receivablesInfoService.list(voQueryWrapper);
                List<ReceivablesRestVo> receivablesList = new ArrayList<>();
                //遍历待缴费信息赋值到对应的返回vo类里面
                if (detailList != null) {
                    detailList.forEach(detail -> {
                        ReceivablesRestVo restVo = new ReceivablesRestVo();
                        BeanUtils.copyProperties(detail, restVo, "paymentInstructions");
                        restVo.setEndDate(DateUtils.formatDate(detail.getEndTime()));
                        restVo.setStartDate(DateUtils.formatDate(detail.getStartTime()));
                        restVo.setAmountMoney(detail.getUnAmountMoney());
                        restVo.setPaymentInstructions(dictService.queryDictTextByKey("payment_instructions", String.valueOf(detail.getPaymentInstructions())));
                        receivablesList.add(restVo);
                    });
                }
                vo.setReceivablesList(receivablesList);
                voList.add(vo);
            });
            Page<ReceivablesRestBaVo> pageList = new Page<>();
            BeanUtils.copyProperties(receivablesInfoIPage, pageList, "records");
            pageList.setRecords(voList);
            return ApiDataUtils.getResponseData(Result.ok(pageList), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        }
    }

    @ApiOperation(value = "待缴费信息-缴费确认", notes = "待缴费信息-缴费确认")
    @PostMapping(value = "/paymentConfirmation")
    public ResponseData<String> paymentConfirmation(@RequestBody String message) {

        RequestData<PaymentConfirmationParamVo> dataReslt = ApiDataUtils.getRequestData(message, PaymentConfirmationParamVo.class);
        try {
            PaymentConfirmationParamVo vo = dataReslt.getBody();
            boolean bool = receivablesInfoService.paymentConfirmation(vo);

            if (bool) {
                return ApiDataUtils.getResponseData(Result.ok("ok！"), dataReslt.getHead());
            } else {
                return ApiDataUtils.getResponseData(Result.error("支付处理失败！"), dataReslt.getHead());
            }
        } catch (JeecgBootException e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error("支付处理失败！"), dataReslt.getHead());
        }

    }

    @ApiOperation(value = "缴费信息-预存缴费", notes = "缴费信息-预存缴费")
    @PostMapping(value = "/paymentPrestore")
    public ResponseData<String> paymentPrestore(@RequestBody String message) {

        RequestData<PaymentParamVo> dataReslt = ApiDataUtils.getRequestData(message, PaymentParamVo.class);
        try {
            PaymentParamVo vo = dataReslt.getBody();
            //预存处理
            boolean bool = orderPrestoreService.saveAndCustomerBalance(vo);
            if (bool) {
                return ApiDataUtils.getResponseData(Result.ok("预存成功！"), dataReslt.getHead());
            } else {
                return ApiDataUtils.getResponseData(Result.error("预存处理失败！"), dataReslt.getHead());
            }
        } catch (JeecgBootException e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error("预存处理失败！"), dataReslt.getHead());
        }
    }

    @ApiOperation(value = "缴费信息-查询预存缴费记录", notes = "缴费信息-查询预存缴费记录")
    @PostMapping(value = "/queryPaymentPrestore")
    public ResponseData<String> queryPaymentPrestore(@RequestBody String message) {

        RequestData<QueryOrdersParamVo> dataReslt = ApiDataUtils.getRequestData(message, QueryOrdersParamVo.class);
        try {
            QueryOrdersParamVo vo = dataReslt.getBody();
            String validateResult = ValidatorUtils.validateFastStr(vo);
            if (validateResult != null) {
                return ApiDataUtils.getResponseData(Result.errorValidation(validateResult), dataReslt.getHead());
            }
//            if (vo.getCustomersIds().length == 0) {
//                return ApiDataUtils.getResponseData(Result.error("客户ID不能为空！"), dataReslt.getHead());
//            }
            QueryWrapper<OrderPrestore> queryWrapper = new QueryWrapper<>();
            if (StringUtils.isNotBlank(vo.getRecordedCompanyName())) {
                String companyId = sysDepartService.selectCompanyIdByName(vo.getRecordedCompanyName());
                if (StringUtils.isBlank(companyId)) {
                    return ApiDataUtils.getResponseData(Result.errorValidation("公司名称信息错误！"), dataReslt.getHead());
                }
                queryWrapper.lambda().eq(OrderPrestore::getRentCompanyId, companyId);
            }
            queryWrapper.lambda().eq(OrderPrestore::getCustomerId, vo.getCustomerId());
            queryWrapper.lambda().orderByDesc(IdBaseEntity::getId);
            //查询预存缴费订单信息
            IPage<OrderPrestore> orderPrestoreIPage = orderPrestoreService.page(new Page<>(vo.getPageNo(), vo.getPageSize()), queryWrapper);
            List<PaymentPrestoreVo> voList = new ArrayList<>();
            orderPrestoreIPage.getRecords().forEach(prestore -> {
                PaymentPrestoreVo restVo = new PaymentPrestoreVo();
                BeanUtils.copyProperties(prestore, restVo);
                restVo.setTradeTime(DateUtils.formatDateTime(prestore.getTradeTime()));
                restVo.setRecordedCompanyName(sysDepartService.getNameById(prestore.getRentCompanyId()));
                AssetInfo assetInfo = assetInfoService.getByContractNum(prestore.getContractNum());
                if (assetInfo != null) {
                    restVo.setSite(assetInfo.getSite());
                }
                voList.add(restVo);
            });

            Page<PaymentPrestoreVo> pageList = new Page<>();
            BeanUtils.copyProperties(orderPrestoreIPage, pageList, "records");
            pageList.setRecords(voList);
            return ApiDataUtils.getResponseData(Result.ok(pageList), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        }
    }

    @ApiOperation(value = "缴费信息-查询自动扣费记录", notes = "缴费信息-查询自动扣费记录")
    @PostMapping(value = "/queryAutomaticDeduction")
    public ResponseData<String> queryAutomaticDeduction(@RequestBody String message) {

        RequestData<QueryOrdersParamVo> dataReslt = ApiDataUtils.getRequestData(message, QueryOrdersParamVo.class);
        try {
            QueryOrdersParamVo vo = dataReslt.getBody();
            String validateResult = ValidatorUtils.validateFastStr(vo);
            if (validateResult != null) {
                return ApiDataUtils.getResponseData(Result.errorValidation(validateResult), dataReslt.getHead());
            }
//            if (vo.getCustomersIds().length == 0) {
//                return ApiDataUtils.getResponseData(Result.error("客户ID不能为空！"), dataReslt.getHead());
//            }

            //查询预存扣费订单信息
            QueryWrapper<OrderDetails> queryWrapper = new QueryWrapper<>();
            OrderDetails orderDetails = new OrderDetails();
            if (StringUtils.isNotBlank(vo.getRecordedCompanyName())) {
                String companyId = sysDepartService.selectCompanyIdByName(vo.getRecordedCompanyName());
                if (StringUtils.isBlank(companyId)) {
                    return ApiDataUtils.getResponseData(Result.errorValidation("公司名称信息错误！"), dataReslt.getHead());
                }
                orderDetails.setRentCompanyId(companyId);
            }
            orderDetails.setPayStatus(AttentionPayStatusEnum.SUCCESSFUL.getStatus());
            orderDetails.setPayType(PayTypeEnum.AUTOMATIC_DEDUCTION.getStatus());
            orderDetails.setOrderType(OrderTypeEnum.AUTOMATIC_DEDUCTION.getStatus());
            queryWrapper.setEntity(orderDetails);
            queryWrapper.lambda().orderByDesc(OrderDetails::getPayDate);
            queryWrapper.lambda().in(OrderDetails::getPaymentBy, vo.getCustomerId());
            queryWrapper.lambda().orderByDesc(IdBaseEntity::getId);
            IPage<OrderDetails> receivablesInfoIPage = orderDetailsService.page(new Page<>(vo.getPageNo(), vo.getPageSize()), queryWrapper);

            List<OrderDetailsBVo> voList = new ArrayList<>();
            receivablesInfoIPage.getRecords().forEach(info -> {
                OrderDetailsBVo restVo = new OrderDetailsBVo();
                BeanUtils.copyProperties(info, restVo);
                restVo.setRecordedCompanyName(sysDepartService.getNameById(info.getRentCompanyId()));
                restVo.setContractNum(dictService.queryTableDictTextByKey("zcgl_lease_contract_info", "contract_num", "id", info.getLeaseContractId()));
                if (StringUtils.isNotBlank(info.getAssetId())) {
                    restVo.setAssetSite(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info", "site", "id", info.getAssetId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }
                if (StringUtils.isNotBlank(info.getCustomerId())) {
                    restVo.setCustomerName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_customer_info", "name", "id", info.getCustomerId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }
                if (StringUtils.isNotBlank(info.getAssetSubIds())) {
                    restVo.setAssetDetailsRoomName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info_sub", "room_name", "id", info.getAssetSubIds().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                }
                restVo.setEndDate(DateUtils.formatDate(info.getEndTime()));
                restVo.setStartDate(DateUtils.formatDate(info.getStartTime()));
                restVo.setAutomaticDeductionDate(DateUtils.formatDateTime(info.getPayDate()));
                restVo.setPaymentInstructions(dictService.queryDictTextByKey("payment_instructions", String.valueOf(info.getPaymentInstructions())));
                voList.add(restVo);
            });

            Page<OrderDetailsBVo> pageList = new Page<>();
            BeanUtils.copyProperties(receivablesInfoIPage, pageList, "records");
            pageList.setRecords(voList);
            return ApiDataUtils.getResponseData(Result.ok(pageList), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        }
    }

    @ApiOperation(value = "缴费信息-缴费记录查询", notes = "缴费信息-缴费记录查询")
    @PostMapping(value = "/queryPaymentList")
    public ResponseData<String> queryPaymentList(@RequestBody String message) {

        RequestData<QueryOrdersParamVo> dataReslt = ApiDataUtils.getRequestData(message, QueryOrdersParamVo.class);
        try {
            QueryOrdersParamVo paramVo = dataReslt.getBody();
            String validateResult = ValidatorUtils.validateFastStr(paramVo);
            if (validateResult != null) {
                return ApiDataUtils.getResponseData(Result.errorValidation(validateResult), dataReslt.getHead());
            }

//            if (paramVo.getCustomersIds().length == 0) {
//                return ApiDataUtils.getResponseData(Result.error("客户ID不能为空！"), dataReslt.getHead());
//            }
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
//            final String customerSql = QueryGenerator.getCustomerSql(Arrays.asList(paramVo.getCustomersId()));
//            queryWrapper.and(i -> i.apply(customerSql));
            if (StringUtils.isNotBlank(paramVo.getRecordedCompanyName())) {
                String companyId = sysDepartService.selectCompanyIdByName(paramVo.getRecordedCompanyName());
                if (StringUtils.isBlank(companyId)) {
                    return ApiDataUtils.getResponseData(Result.errorValidation("公司名称信息错误！"), dataReslt.getHead());
                }
                queryWrapper.lambda().eq(Order::getRentCompanyId, companyId);
            }
            queryWrapper.lambda().eq(Order::getCustomerId, paramVo.getCustomerId());
            queryWrapper.lambda().eq(Order::getOrderType, OrderTypeEnum.INITIATIVE_PAY.getStatus());
            queryWrapper.lambda().orderByDesc(IdBaseEntity::getId);
            //查询缴费订单信息
            IPage<Order> orderIPage = orderService.page(new Page<>(paramVo.getPageNo(), paramVo.getPageSize()), queryWrapper);
            List<OrderDetailsRestVo> voList = new ArrayList<>();
            orderIPage.getRecords().stream().forEach(info -> {
                OrderDetailsRestVo vo = new OrderDetailsRestVo();
                BeanUtils.copyProperties(info, vo);
                vo.setTradeTime(DateUtils.formatDateTime(info.getTradeTime()));
//                vo.setOrderType(dictService.queryDictTextByKey("zcgl_order_type", String.valueOf(info.getOrderType())));
                List<OrderDetailsRestDetailVo> orderDetailsRestDetailVos = new ArrayList<>();
                //查询缴费订单详情
                List<OrderDetails> orderDetails = orderDetailsService.selectByMainId(info.getId());
                if (orderDetails != null) {
                    orderDetails.stream().forEach(details -> {
                        OrderDetailsRestDetailVo detailVo = new OrderDetailsRestDetailVo();
                        BeanUtils.copyProperties(details, detailVo);
                        detailVo.setRecordedCompanyName(sysDepartService.getNameById(details.getRentCompanyId()));
                        detailVo.setContractNum(dictService.queryTableDictTextByKey("zcgl_lease_contract_info", "contract_num", "id", details.getLeaseContractId()));
                        if (StringUtils.isNotBlank(details.getAssetId())) {
                            detailVo.setAssetSite(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info", "site", "id", details.getAssetId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                        }
                        if (StringUtils.isNotBlank(details.getCustomerId())) {
                            detailVo.setCustomerName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_customer_info", "name", "id", details.getCustomerId().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                        }
                        if (StringUtils.isNotBlank(details.getAssetSubIds())) {
                            detailVo.setAssetDetailsRoomName(StringUtils.join(dictService.queryTableDictByKeys("zcgl_asset_info_sub", "room_name", "id", details.getAssetSubIds().split(CommonConstant.DEFAULT_SEPARATOR)), CommonConstant.DEFAULT_SEPARATOR));
                        }
                        detailVo.setPaymentInstructions(dictService.queryDictTextByKey("payment_instructions", String.valueOf(details.getPaymentInstructions())));
                        detailVo.setEndDate(DateUtils.formatDate(details.getEndTime()));
                        detailVo.setStartDate(DateUtils.formatDate(details.getStartTime()));
                        orderDetailsRestDetailVos.add(detailVo);
                    });
                }
                vo.setOrderDetails(orderDetailsRestDetailVos);

                voList.add(vo);
            });
            Page<OrderDetailsRestVo> pageList = new Page<>();
            BeanUtils.copyProperties(orderIPage, pageList, "records");
            pageList.setRecords(voList);
            return ApiDataUtils.getResponseData(Result.ok(pageList), dataReslt.getHead());
        } catch (Exception e) {
            e.printStackTrace();
            return ApiDataUtils.getResponseData(Result.error(e.getMessage()), dataReslt.getHead());
        }
    }
}
